package com.smart.community.property.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.smart.community.commons.annotation.ApiLog;
import com.smart.community.commons.enums.ApiLogOperationType;
import com.smart.community.commons.result.Result;
import com.smart.community.property.dto.BillingMethodDTO;
import com.smart.community.property.dto.BillingMethodQueryDTO;
import com.smart.community.property.service.IBillingMethodService;
import com.smart.community.property.vo.BillingMethodVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

/**
 * 计费方式管理Controller
 * 
 * @author Wu.Liang
 * @since 2025-01-30
 * @version 1.0.0
 */
@Slf4j
@RestController
@RequestMapping("/property/billing-method")
@Tag(name = "计费方式管理", description = "计费方式相关接口")
@Validated
public class BillingMethodController {

    @Autowired
    private IBillingMethodService billingMethodService;

    /**
     * 分页查询计费方式
     * 
     * @param query 查询条件
     * @return 分页结果
     * @throws Exception 统一异常
     */
    @PostMapping("/page")
    @Operation(summary = "分页查询计费方式", description = "根据条件分页查询计费方式列表")
    public Result<IPage<BillingMethodVO>> getBillingMethodPage(@RequestBody @Valid BillingMethodQueryDTO query) throws Exception {
        IPage<BillingMethodVO> result = billingMethodService.getBillingMethodPage(query);
        return Result.success(result);
    }

    /**
     * 根据物业公司ID和费用类型查询计费方式列表
     * 
     * @param propertyCompanyId 物业公司ID
     * @param feeType 费用类型
     * @param buildingTypeName 建筑类型名称
     * @return 计费方式列表
     * @throws Exception 统一异常
     */
    @GetMapping("/list")
    @Operation(summary = "查询计费方式列表", description = "根据物业公司ID和费用类型查询计费方式列表")
    public Result<List<BillingMethodVO>> getBillingMethodList(
        @Parameter(description = "物业公司ID") @RequestParam Long propertyCompanyId,
        @Parameter(description = "费用类型") @RequestParam String feeType,
        @Parameter(description = "建筑类型名称") @RequestParam(required = false) String buildingTypeName) throws Exception {
        List<BillingMethodVO> result = billingMethodService.getBillingMethodsByPropertyCompanyAndFeeType(
            propertyCompanyId, feeType, buildingTypeName);
        return Result.success(result);
    }

    /**
     * 根据物业公司ID列表和费用类型查询计费方式列表
     * 
     * @param propertyCompanyIds 物业公司ID列表
     * @param feeType 费用类型
     * @param buildingTypeName 建筑类型名称
     * @return 计费方式列表
     * @throws Exception 统一异常
     */
    @PostMapping("/list/multi-company")
    @Operation(summary = "查询多公司计费方式列表", description = "根据物业公司ID列表和费用类型查询计费方式列表")
    public Result<List<BillingMethodVO>> getBillingMethodListByMultiCompany(
        @Parameter(description = "物业公司ID列表") @RequestParam List<Long> propertyCompanyIds,
        @Parameter(description = "费用类型") @RequestParam String feeType,
        @Parameter(description = "建筑类型名称") @RequestParam(required = false) String buildingTypeName) throws Exception {
        List<BillingMethodVO> result = billingMethodService.getBillingMethodsByPropertyCompanyIdsAndFeeType(
            propertyCompanyIds, feeType, buildingTypeName);
        return Result.success(result);
    }

    /**
     * 根据ID查询计费方式详情
     * 
     * @param id 计费方式ID
     * @return 计费方式详情
     * @throws Exception 统一异常
     */
    @GetMapping("/{id}")
    @Operation(summary = "查询计费方式详情", description = "根据ID查询计费方式详情")
    public Result<BillingMethodVO> getBillingMethodDetail(
        @Parameter(description = "计费方式ID") @PathVariable Long id) throws Exception {
        BillingMethodVO result = billingMethodService.getBillingMethodDetail(id);
        return Result.success(result);
    }

    /**
     * 创建计费方式
     * 
     * @param dto 计费方式DTO
     * @return 计费方式ID
     * @throws Exception 统一异常
     */
    @PostMapping
    @Operation(summary = "创建计费方式", description = "创建新的计费方式")
    @ApiLog(
        logTitle = "创建计费方式",
        logType = 2,
        moduleName = "物业管理",
        operationType = ApiLogOperationType.ADD
    )
    public Result<Long> createBillingMethod(@RequestBody @Valid BillingMethodDTO dto) throws Exception {
        Long id = billingMethodService.createBillingMethod(dto);
        return Result.success(id);
    }

    /**
     * 更新计费方式
     * 
     * @param dto 计费方式DTO
     * @return 操作结果
     * @throws Exception 统一异常
     */
    @PutMapping
    @Operation(summary = "更新计费方式", description = "更新计费方式信息")
    @ApiLog(
        logTitle = "更新计费方式",
        logType = 2,
        moduleName = "物业管理",
        operationType = ApiLogOperationType.UPDATE
    )
    public Result<Void> updateBillingMethod(@RequestBody @Valid BillingMethodDTO dto) throws Exception {
        billingMethodService.updateBillingMethod(dto);
        return Result.success();
    }

    /**
     * 删除计费方式
     * 
     * @param id 计费方式ID
     * @return 操作结果
     * @throws Exception 统一异常
     */
    @DeleteMapping("/{id}")
    @Operation(summary = "删除计费方式", description = "根据ID删除计费方式")
    @ApiLog(
        logTitle = "删除计费方式",
        logType = 2,
        moduleName = "物业管理",
        operationType = ApiLogOperationType.DELETE
    )
    public Result<Void> deleteBillingMethod(
        @Parameter(description = "计费方式ID") @PathVariable Long id) throws Exception {
        billingMethodService.deleteBillingMethod(id);
        return Result.success();
    }

    /**
     * 批量删除计费方式
     * 
     * @param ids 计费方式ID列表
     * @return 操作结果
     * @throws Exception 统一异常
     */
    @DeleteMapping("/batch")
    @Operation(summary = "批量删除计费方式", description = "批量删除计费方式")
    @ApiLog(
        logTitle = "批量删除计费方式",
        logType = 2,
        moduleName = "物业管理",
        operationType = ApiLogOperationType.DELETE
    )
    public Result<Void> batchDeleteBillingMethods(
        @Parameter(description = "计费方式ID列表") @RequestBody List<Long> ids) throws Exception {
        billingMethodService.batchDeleteBillingMethods(ids);
        return Result.success();
    }

    /**
     * 根据建筑类型名称查询适用的计费方式
     * 
     * @param propertyCompanyId 物业公司ID
     * @param feeType 费用类型
     * @param buildingTypeName 建筑类型名称
     * @return 计费方式列表
     * @throws Exception 统一异常
     */
    @GetMapping("/applicable")
    @Operation(summary = "查询适用的计费方式", description = "根据建筑类型名称查询适用的计费方式")
    public Result<List<BillingMethodVO>> getApplicableBillingMethods(
        @Parameter(description = "物业公司ID") @RequestParam Long propertyCompanyId,
        @Parameter(description = "费用类型") @RequestParam String feeType,
        @Parameter(description = "建筑类型名称") @RequestParam String buildingTypeName) throws Exception {
        List<BillingMethodVO> result = billingMethodService.getApplicableBillingMethodsByBuildingType(
            propertyCompanyId, feeType, buildingTypeName);
        return Result.success(result);
    }
}
